package com.rimi.servlet;

import com.alibaba.fastjson.JSONObject;
import com.rimi.bean.JsonResult;
import com.rimi.bean.Menu;
import com.rimi.bean.Role;
import com.rimi.bean.User;
import com.rimi.service.MenuService;
import com.rimi.service.RoleService;
import com.rimi.service.UserService;
import com.rimi.service.impl.MenuServiceImpl;
import com.rimi.service.impl.RoleServiceImpl;
import com.rimi.service.impl.UserServiceImpl;
import com.wf.captcha.utils.CaptchaUtil;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author chengliang
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    private UserService userService;
    private RoleService roleService;
    private MenuService menuService;

    public LoginServlet(){
        userService = new UserServiceImpl();
        roleService = new RoleServiceImpl();
        menuService = new MenuServiceImpl();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //接收登录信息
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String vercode = request.getParameter("vercode");
        //验证验证码
        if (!CaptchaUtil.ver(vercode, request)) {
            //清除掉生成的验证码
            CaptchaUtil.clear(request);
            //实例化 json响应对象
            JsonResult jsonResult = JsonResult.ERROR("验证码输入错误");
            //将对象转换为json字符串
            String jsonString = JSONObject.toJSONString(jsonResult);
            writer.append(jsonString);
            return;
        }
        //验证登录信息
        User user = userService.login(username, password);
        if(user == null){
            writer.append(JsonResult.ERROR("账号或密码输入有误").toJson());
            return;
        }
        //验证账号是否被禁用
        if(user.getUserEnable() == 1){
            writer.append(JsonResult.ERROR("该账户已被禁用，请联系管理员").toJson());
            return;
        }
        //该账户的角色被禁用
        Role role = roleService.getRoleByRoleId(user.getRoleId());
        if(role == null || role.getRoleEnable() == 1){
            writer.append(JsonResult.ERROR("该账户的角色已被禁用，请联系管理员").toJson());
            return;
        }
        //判断是否需要记住密码
        if("1".equals(request.getParameter("remember"))){
            //账号信息肯定是加密以后。
            Cookie usernameCookie = new Cookie("username",username);
            Cookie passwordCookie = new Cookie("password",password);
            //设置存活时间 单位:秒   七天免登录时间 : 60 * 60 * 24 * 7
            usernameCookie.setMaxAge(30);
            passwordCookie.setMaxAge(30);
            response.addCookie(usernameCookie);
            response.addCookie(passwordCookie);
        }
        ServletContext servletContext = request.getServletContext();
        //登录成功,将用户添加到用户列表中
        //重写比较器
        Set<User> onlineUser = new HashSet<>();
        //判断在线用户列表中是否存在用户
        Object object = servletContext.getAttribute("onlineUser");
        if(object != null){
            onlineUser = (Set<User>)object;
        }
        boolean isok = true;
        //检查在线用户列表中 是否存在该用户
        for (User u : onlineUser) {
            if(u.getUserId().equals(user.getUserId())){
                isok = false;
            }
        }
        if(isok){
            onlineUser.add(user);
        }
        //存储到ServletContext中
        servletContext.setAttribute("onlineUser",onlineUser);
        //将账户拥有的菜单项 显示到页面中
        List<Menu> menuList = menuService.getMenuListByRoleId(user.getRoleId());
        //将当前登录人的信息存储起来 request作用域:一次请求
        //作用域:
        // 四大作用域: request 、session 一次会话（多次请求）、ServletContext 一次服务(服务器启动到关闭)、 cookie（存储在客户端、浏览器）
        // 三大作用域: request 、session 一次会话（多次请求）、ServletContext 一次服务(服务器启动到关闭)
        // session对象：每一个客户端都拥有一个对应的session对象。session默认无操作的情况下，30分钟销毁。
        // 如果session对象不存在则 新创建一个session给用户使用
        // session 第一部分: session对象 第二部分:sessionId
        // 当用户、浏览器 请求服务器的时候。如果没有sessionId，创建session对象并生成一个SessionId 响应给客户端存储起来。
        // 如果有sessionId，则按照sessionId找到一个对应的session对象去使用。
        // 如果有sessionId但是session对象因为超时已经销毁了。通过sessionID去获取session对象，找不到session。重新创建一个session对象
        // 并重新生成sessionId，响应给浏览器、客户端 将原来的sessionId覆盖掉；
        HttpSession session = request.getSession();
        session.setAttribute("user",user);
        session.setAttribute("menuList",menuList);
        writer.append(JsonResult.SUCCESS("登录成功").toJson());
        writer.close();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
        //跳转到登录页面
        //response.sendRedirect("/");
    }
}
